package frsf.cidisi.exercise.arq.search.actions;

import java.util.ArrayList;

import frsf.cidisi.exercise.arq.search.*;
import frsf.cidisi.faia.agent.search.SearchAction;
import frsf.cidisi.faia.agent.search.SearchBasedAgentState;
import frsf.cidisi.faia.state.AgentState;
import frsf.cidisi.faia.state.EnvironmentState;

public class IrACabe extends SearchAction {

	/**
	 * This method updates a tree node state when the search process is running.
	 * It does not updates the real world state.
	 */
	@Override
	public SearchBasedAgentState execute(SearchBasedAgentState s) {
		EstadoArqueologo agState = (EstadoArqueologo) s;

		ArrayList<String> ciudadesAdyacentes = new ArrayList<String>();
		ciudadesAdyacentes.addAll(agState.getCiudadesAdyacentes());

		if (ciudadesAdyacentes != null) {
			int index = ciudadesAdyacentes.indexOf(EstadoArqueologo.Ca);
			if (index >= 0) {

				/* actualizamos la distancia total recorrida por el agente */
				int distActualTemp = agState.getdistanciaActual();
				int distTemp = agState.calcularDistancia(EstadoArqueologo.Ca);
				agState.setdistanciaActual(distActualTemp + distTemp);

				/* actualizamos la posicion del agente */
				agState.setposicion(EstadoArqueologo.Ca);

				/* actualizamos la lista de ciudades visitadas */
				agState.addCiudadVisitada(EstadoArqueologo.Ca);

				return agState;
			}
		}
		return null;
	}

	/**
	 * This method updates the agent state and the real world state.
	 */
	@Override
	public EnvironmentState execute(AgentState ast, EnvironmentState est) {
		EstadoIsla environmentState = (EstadoIsla) est;
		EstadoArqueologo agState = ((EstadoArqueologo) ast);

		ArrayList<String> ciudadesAdyacentes = new ArrayList<String>();
		ciudadesAdyacentes.addAll(environmentState.getCiudadesAdyacentesArq());

		if (ciudadesAdyacentes != null) {
			int index = ciudadesAdyacentes.indexOf(EstadoIsla.Ca);
			if (index >= 0) {
				/** actualizamos el estado del mundo real */
				environmentState.setposicionArqueologo(EstadoIsla.Ca);

				/** actualizamos el estado del agente */
				/* calculamos la distancia actual recorrida por el agente */
				int distActualTemp = agState.getdistanciaActual();
				int distTemp = agState.calcularDistancia(EstadoArqueologo.Ca);
				agState.setdistanciaActual(distActualTemp + distTemp);

				agState.setposicion(EstadoArqueologo.Ca);

				/* actualizamos la lista de ciudades visitadas */
				agState.addCiudadVisitada(EstadoArqueologo.Ca);
				return environmentState;
			}
		}
		/*
		 * no hay ciudades adyacentes, o Cabe no es una de las ciudades
		 * adyacentes
		 */
		return null;
	}

	/**
	 * This method returns the action cost.
	 */
	@Override
	public Double getCost() {
		return new Double(0);
	}

	/**
	 * This method is not important for a search based agent, but is essensial
	 * when creating a calculus based one.
	 */
	@Override
	public String toString() {
		return "IrACabe";
	}
}